<template>
  <div class="file-tree">
    <div
      v-for="item in flatItems"
      :id="item.id"
      class="tree-item"
      :style="{ paddingLeft: `${item.depth * 20 + 10}px` }"
    >
      <!-- 箭头图标 (仅文件夹有) -->
      <span v-if="item.type === 'folder'" class="toggle-icon" @click="toggleFolder(item.id)">
        <svg
          :class="['arrow-icon', { expanded: item.expanded }]"
          viewBox="0 0 10 10"
          width="10"
          height="10"
        >
          <path d="M 2 2 L 8 5 L 2 8 Z" />
        </svg>
      </span>
      <!-- 图标 (文件夹或文件) -->
      <span class="icon">
        <!-- 核心修改：根据文件夹展开状态选择图标 -->
        <template v-if="item.type === 'folder'">
          {{ item.expanded ? '📂' : '📁' }}
        </template>
        <template v-else> 📄 </template>
      </span>
      <!-- 名称 -->
      <span
        v-if="item.type === 'file'"
        :class="
          selectedId === item.id
            ? 'item-name file-clickable item-name-active'
            : 'item-name file-clickable'
        "
        @click="item.type === 'file' ? selectFile(item) : null"
        :title="item.name"
      >
        {{ item.name }}
      </span>
      <span v-else :title="item.name" class="item-name">
        {{ item.name }}
      </span>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

// 定义 props
const props = defineProps({
  items: {
    type: Array,
    required: true
  }
})

// 定义事件
const emit = defineEmits(['file-selected'])
const selectedId = ref(null)

// 管理每个节点的展开状态 (使用id作为键)
const expandedState = ref({})

// 递归函数：将嵌套树结构转换为扁平列表
const flattenTree = (items, depth = 0, parentPath = '') => {
  let result = []
  items.forEach((item) => {
    // 为每个节点生成唯一ID (基于路径)
    let id = item.id
    if (!id) {
      id = parentPath ? `${parentPath}/${item.name}` : item.name
    }
    // 获取或初始化该节点的展开状态
    const isExpanded =
      expandedState.value[id] !== undefined ? expandedState.value[id] : item.expanded || false

    // 将当前节点添加到结果中
    result.push({
      ...item,
      id,
      depth,
      expanded: isExpanded
    })

    // 如果是文件夹且已展开，则递归处理其子项
    if (item.type === 'folder' && isExpanded && item.children) {
      result = result.concat(flattenTree(item.children, depth + 1, id))
    }
  })
  return result
}

// 计算属性：生成当前应显示的扁平化列表
const flatItems = computed(() => {
  return flattenTree(props.items)
})

// 切换文件夹展开/折叠
const toggleFolder = (id) => {
  // 切换指定id节点的状态
  expandedState.value = {
    ...expandedState.value,
    [id]: !expandedState.value[id]
  }
}

// 选择文件
const selectFile = (file) => {
  selectedId.value = file.id
  emit('file-selected', file)
}
</script>

<style scoped>
.file-tree {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  font-size: 14px;
  color: #333;
  line-height: 1.6;
  border: 1px solid #ddd;
  border-radius: 6px;
  overflow: hidden;
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.tree-item {
  display: flex;
  align-items: center;
  padding: 6px 12px;
  border-bottom: 1px solid #eee;
  transition: background-color 0.15s ease;
}

.tree-item:hover {
  background-color: #f5f7fa;
}

/* 箭头图标 */
.toggle-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-right: 8px;
  color: #666;
  cursor: pointer;
  transition: transform 0.2s ease;
}

.arrow-icon {
  fill: currentColor;
  transition: transform 0.2s ease;
}

.arrow-icon.expanded {
  transform: rotate(90deg);
}

/* 图标 */
.icon {
  margin-right: 10px;
  font-size: 16px;
}

/* 文件名 */
.item-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-name-active {
  color: #007bff;
  text-decoration: underline;
}

/* 文件可点击样式 */
.file-clickable {
  cursor: pointer;
}

.file-clickable:hover {
  color: #007bff;
  text-decoration: underline;
}
</style>
